package fhq.hcmute.edu.vn.keyboard;
/**
 * 
 */

import java.awt.event.KeyEvent;
import java.io.Serializable;

/**
 * @author Hien Nguyen Sep 28, 2012
 */
public enum KeyCode implements Serializable {

	a(KeyEvent.VK_A), b(KeyEvent.VK_B), c(KeyEvent.VK_C), d(KeyEvent.VK_D),
	e(KeyEvent.VK_E), f(KeyEvent.VK_F), g(KeyEvent.VK_G), h(KeyEvent.VK_H),
	i(KeyEvent.VK_I), j(KeyEvent.VK_J), k(KeyEvent.VK_K), l(KeyEvent.VK_L),
	m(KeyEvent.VK_M), n(KeyEvent.VK_N), o(KeyEvent.VK_O), p(KeyEvent.VK_P),
	q(KeyEvent.VK_Q), r(KeyEvent.VK_R), s(KeyEvent.VK_S), t(KeyEvent.VK_T),
	u(KeyEvent.VK_U), v(KeyEvent.VK_V), w(KeyEvent.VK_W), x(KeyEvent.VK_X),
	y(KeyEvent.VK_Y), z(KeyEvent.VK_Z),
	A(KeyEvent.VK_SHIFT, KeyEvent.VK_A), B(KeyEvent.VK_SHIFT, KeyEvent.VK_B),
	C(KeyEvent.VK_SHIFT, KeyEvent.VK_C), D(KeyEvent.VK_SHIFT, KeyEvent.VK_D),
	E(KeyEvent.VK_SHIFT, KeyEvent.VK_E), F(KeyEvent.VK_SHIFT, KeyEvent.VK_F),
	G(KeyEvent.VK_SHIFT, KeyEvent.VK_G), H(KeyEvent.VK_SHIFT, KeyEvent.VK_H),
	I(KeyEvent.VK_SHIFT, KeyEvent.VK_I), J(KeyEvent.VK_SHIFT, KeyEvent.VK_J),
	K(KeyEvent.VK_SHIFT, KeyEvent.VK_K), L(KeyEvent.VK_SHIFT, KeyEvent.VK_L),
	M(KeyEvent.VK_SHIFT, KeyEvent.VK_M), N(KeyEvent.VK_SHIFT, KeyEvent.VK_N),
	O(KeyEvent.VK_SHIFT, KeyEvent.VK_O), P(KeyEvent.VK_SHIFT, KeyEvent.VK_P),
	Q(KeyEvent.VK_SHIFT, KeyEvent.VK_Q), R(KeyEvent.VK_SHIFT, KeyEvent.VK_R),
	S(KeyEvent.VK_SHIFT, KeyEvent.VK_S), T(KeyEvent.VK_SHIFT, KeyEvent.VK_T),
	U(KeyEvent.VK_SHIFT, KeyEvent.VK_U), V(KeyEvent.VK_SHIFT, KeyEvent.VK_V),
	W(KeyEvent.VK_SHIFT, KeyEvent.VK_W), X(KeyEvent.VK_SHIFT, KeyEvent.VK_X),
	Y(KeyEvent.VK_SHIFT, KeyEvent.VK_Y), Z(KeyEvent.VK_SHIFT, KeyEvent.VK_Z),

	AT(KeyEvent.VK_SHIFT, KeyEvent.VK_2),
	BACK_SLASH(KeyEvent.VK_BACK_SLASH),
	CIRCUMFLEX(KeyEvent.VK_SHIFT, KeyEvent.VK_6),
	CLOSE_BRACKET(KeyEvent.VK_CLOSE_BRACKET),
	CLOSE_BRACKET_1(KeyEvent.VK_SHIFT, KeyEvent.VK_CLOSE_BRACKET),
	COLON(KeyEvent.VK_SHIFT, KeyEvent.VK_SEMICOLON),
	COMMA(KeyEvent.VK_COMMA),
	DOLLAR(KeyEvent.VK_SHIFT, KeyEvent.VK_4),
	EQUALS(KeyEvent.VK_EQUALS),
	EXCLAMATION_MARK(KeyEvent.VK_SHIFT, KeyEvent.VK_1),
	LEFT_PARENTHESIS(KeyEvent.VK_SHIFT, KeyEvent.VK_9),
	MINUS(KeyEvent.VK_MINUS),
	NUMBER_SIGN(KeyEvent.VK_SHIFT, KeyEvent.VK_3),
	OPEN_BRACKET(KeyEvent.VK_OPEN_BRACKET),
	OPEN_BRACKET_1(KeyEvent.VK_SHIFT, KeyEvent.VK_OPEN_BRACKET),
	PERIOD(KeyEvent.VK_PERIOD),
	PLUS(KeyEvent.VK_SHIFT, KeyEvent.VK_EQUALS),
	SEMICOLON(KeyEvent.VK_SEMICOLON),
	SLASH(KeyEvent.VK_SLASH),
	SPACE(KeyEvent.VK_SPACE),
	UNDERSCORE(KeyEvent.VK_SHIFT, KeyEvent.VK_MINUS),
	UNDEFINED(KeyEvent.VK_UNDEFINED),
	ASTERISK(KeyEvent.VK_SHIFT, KeyEvent.VK_8),
	RIGHT_PARENTHESIS(KeyEvent.VK_SHIFT, KeyEvent.VK_0),
	BACK_QUOTE(KeyEvent.VK_BACK_QUOTE),
	QUOTE(KeyEvent.VK_QUOTE),
	TILDE(KeyEvent.VK_SHIFT, KeyEvent.VK_BACK_QUOTE),
	PERCENT(KeyEvent.VK_SHIFT, KeyEvent.VK_5),
	QUESTION_MARK(KeyEvent.VK_SHIFT, KeyEvent.VK_SLASH),
	GREATER_THAN(KeyEvent.VK_SHIFT, KeyEvent.VK_PERIOD),
	AND(KeyEvent.VK_SHIFT, KeyEvent.VK_7),
	LESS_THAN(KeyEvent.VK_SHIFT, KeyEvent.VK_COMMA),
	DOUBLE_QUOTE(KeyEvent.VK_SHIFT, KeyEvent.VK_QUOTE),
	VERTICAL_BAR(KeyEvent.VK_SHIFT, KeyEvent.VK_BACK_SLASH),
	VK_0(KeyEvent.VK_0),
	VK_1(KeyEvent.VK_1),
	VK_2(KeyEvent.VK_2),
	VK_3(KeyEvent.VK_3),
	VK_4(KeyEvent.VK_4),
	VK_5(KeyEvent.VK_5),
	VK_6(KeyEvent.VK_6),
	VK_7(KeyEvent.VK_7),
	VK_8(KeyEvent.VK_8),
	VK_9(KeyEvent.VK_9),
	ENTER(KeyEvent.VK_ENTER), BACK_SPACE(KeyEvent.VK_BACK_SPACE),
	LEFT(KeyEvent.VK_LEFT), RIGHT(KeyEvent.VK_RIGHT),

	á(), à(), ả(), ã(), ạ(), â(), ấ(), ầ(), ẩ(), ẫ(), ậ(),
	ặ(), ắ(), ằ(), ă(),

	é(), ẻ(), ẹ(), ê(), ế(), ề(), ể(), ễ(), ệ(),

	ý(), ỳ(), ỵ(), ỷ(), ỹ(),

	í(), ì(), ỉ(), ĩ(), ị(),

	ó(), ò(), ỏ(), õ(), ọ(), ô(), ơ(), ố(), ồ(), ổ(), ỗ(), ộ(), ớ(), ờ(),
	ở(), ỡ(), ợ(),

	ú(), ù(), ủ(), ũ(), ụ(), ư(), ứ(), ừ(),
	ử(), ữ(), ự(),

	đ(),

	Á(), À(), Ả(), Ã(), Ạ(), Â(), Ấ(), Ầ(), Ẩ(), Ẫ(), Ậ(),
	Ặ(), Ắ(), Ằ(), Ă(),

	É(), Ẻ(), Ẹ(), Ê(), Ế(), Ề(), Ể(), Ễ(), Ệ(),

	Ý(), Ỳ(), Ỵ(), Ỷ(), Ỹ(),

	Í(), Ì(), Ỉ(), Ĩ(), Ị(),

	Ó(), Ò(), Ỏ(), Õ(), Ọ(), Ô(), Ơ(), Ố(), Ồ(), Ổ(), Ỗ(), Ộ(), Ớ(), Ờ(),
	Ở(), Ỡ(), Ợ(),

	Ú(), Ù(), Ủ(), Ũ(), Ụ(), Ư(), Ứ(), Ừ(),
	Ử(), Ữ(), Ự(),

	Đ();

	private int key2;
	private int key1;
	private int key3;
	private int key4;
	private int key5;
	private int keyCount = 0;
	public static final int TELEX = 1;
	public static final int VNI = -1;

	public int getKey5() {
		return key5;
	}

	public void setKey5(int key5) {
		this.key5 = key5;
	}

	public final int getKey4() {
		return key4;
	}

	public final void setKey4(int key4) {
		this.key4 = key4;
	}

	public final int getKey2() {
		return key2;
	}

	public final void setKey2(int key2) {
		this.key2 = key2;
	}

	public final int getKey1() {
		return key1;
	}

	public final void setKey1(int key1) {
		this.key1 = key1;
	}

	public final int getKey3() {
		return key3;
	}

	public final void setKey3(int key3) {
		this.key3 = key3;
	}

	public final int getKeyCount() {
		return keyCount;
	}

	public final void setKeyCount(int keyCount) {
		this.keyCount = keyCount;
	}

	KeyCode(int key1, int key2) {
		this.key1 = key1;
		this.key2 = key2;
		this.keyCount = 2;
	}

	KeyCode(int key1, int key2, int key3) {
		this.key3 = key3;
		this.key2 = key2;
		this.key1 = key1;
		this.keyCount = 3;
	}

	KeyCode(int key1, int key2, int key3, int key4) {
		this.key1 = key1;
		this.key3 = key3;
		this.key2 = key2;
		this.key4 = key4;
		this.keyCount = 4;
	}

	KeyCode(int key1, int key2, int key3, int key4, int key5) {
		this.key1 = key1;
		this.key3 = key3;
		this.key2 = key2;
		this.key4 = key4;
		this.setKey5(key5);
		this.keyCount = 5;
	}

	private KeyCode(int key1) {
		this.key1 = key1;
		this.keyCount = 1;
	}

	private KeyCode() {
		this.keyCount = 0;
	}

	private static KeyCode specialKeyCode(String text) {
		if (text.equals("@"))
			return AT;
		if (text.equals("_"))
			return UNDERSCORE;
		if (text.equals("\\"))
			return BACK_SLASH;
		if (text.equals("^"))
			return CIRCUMFLEX;
		if (text.equals("]"))
			return CLOSE_BRACKET;
		if (text.equals(":"))
			return COLON;
		if (text.equals(","))
			return COMMA;
		if (text.equals("$"))
			return DOLLAR;
		if (text.equals("="))
			return EQUALS;
		if (text.equals("!"))
			return EXCLAMATION_MARK;
		if (text.equals("("))
			return LEFT_PARENTHESIS;
		if (text.equals("-"))
			return MINUS;
		if (text.equals("#"))
			return NUMBER_SIGN;
		if (text.equals("["))
			return OPEN_BRACKET;
		if (text.equals("."))
			return PERIOD;
		if (text.equals("+"))
			return PLUS;
		if (text.equals(")"))
			return RIGHT_PARENTHESIS;
		if (text.equals(";"))
			return SEMICOLON;
		if (text.equals("/"))
			return SLASH;
		if (text.equals("_"))
			return UNDERSCORE;
		if (text.equals("{"))
			return OPEN_BRACKET_1;
		if (text.equals("}"))
			return CLOSE_BRACKET_1;
		if (text.equals("`"))
			return BACK_QUOTE;
		if (text.equals("~"))
			return TILDE;
		if (text.equals("%"))
			return PERCENT;
		if (text.equals("*"))
			return ASTERISK;
		if (text.equals("|"))
			return VERTICAL_BAR;
		if (text.equals("?"))
			return QUESTION_MARK;
		if (text.equals("<"))
			return LESS_THAN;
		if (text.equals(">"))
			return GREATER_THAN;
		if (text.equals("'"))
			return QUOTE;
		if (text.equals("\""))
			return DOUBLE_QUOTE;
		if (text.equals("&"))
			return AND;
		if (text.equals(" "))
			return SPACE;
		if (text.equals("0"))
			return VK_0;
		if (text.equals("1"))
			return VK_1;
		if (text.equals("2"))
			return VK_2;
		if (text.equals("3"))
			return VK_3;
		if (text.equals("4"))
			return VK_4;
		if (text.equals("5"))
			return VK_5;
		if (text.equals("6"))
			return VK_6;
		if (text.equals("7"))
			return VK_7;
		if (text.equals("8"))
			return VK_8;
		if (text.equals("9"))
			return VK_9;
		return null;
	}

	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return name();
	}

	private static KeyCode swap(KeyCode code, KeyCode_VNI code_VNI) {
		int count = code_VNI.getKeyCount();
		code.keyCount = count;
		switch (count) {
		case 1:
			code.key1 = code_VNI.getKey1();
			break;
		case 2:
			code.key1 = code_VNI.getKey1();
			code.key2 = code_VNI.getKey2();
			break;
		case 3:
			code.key1 = code_VNI.getKey1();
			code.key2 = code_VNI.getKey2();
			code.key3 = code_VNI.getKey3();
			break;
		case 4:
			code.key1 = code_VNI.getKey1();
			code.key2 = code_VNI.getKey2();
			code.key3 = code_VNI.getKey3();
			code.key4 = code_VNI.getKey4();
			break;
		case 5:
			code.key1 = code_VNI.getKey1();
			code.key2 = code_VNI.getKey2();
			code.key3 = code_VNI.getKey3();
			code.key4 = code_VNI.getKey4();
			code.key5 = code_VNI.getKey5();
			break;
		}
		return code;
	}

	private static KeyCode swap(KeyCode code, KeyCode_Telex code_Telex) {
		int count = code_Telex.getKeyCount();
		code.keyCount = count;
		switch (count) {
		case 1:
			code.key1 = code_Telex.getKey1();
			break;
		case 2:
			code.key1 = code_Telex.getKey1();
			code.key2 = code_Telex.getKey2();
			break;
		case 3:
			code.key1 = code_Telex.getKey1();
			code.key2 = code_Telex.getKey2();
			code.key3 = code_Telex.getKey3();
			break;
		case 4:
			code.key1 = code_Telex.getKey1();
			code.key2 = code_Telex.getKey2();
			code.key3 = code_Telex.getKey3();
			code.key4 = code_Telex.getKey4();
			break;
		case 5:
			code.key1 = code_Telex.getKey1();
			code.key2 = code_Telex.getKey2();
			code.key3 = code_Telex.getKey3();
			code.key4 = code_Telex.getKey4();
			code.key5 = code_Telex.getKey5();
			break;
		}
		return code;
	}

	public static KeyCode fromString(String text, int type) {
		if (text != null) {
			KeyCode k = specialKeyCode(text);
			if (k == null) {
				for (KeyCode b : KeyCode.values()) {
					if (text.equals(b.name())) {
						if (b.getKeyCount() == 0) {
							if (type == 1) {
								KeyCode_Telex code_Telex =
										KeyCode_Telex.fromString(text);
								b = swap(b, code_Telex);
							} else if (type == -1) {
								KeyCode_VNI code_VNI =
										KeyCode_VNI.fromString(text);
								b = swap(b, code_VNI);
							}
						}
						return b;
					}
				}
			} else {
				return k;
			}
		}
		return UNDEFINED;
	}

	public static KeyCode fromString(char c, int type) {
		String text = Character.toString(c);
		if (text != null) {
			KeyCode k = specialKeyCode(text);
			if (k == null) {
				for (KeyCode b : KeyCode.values()) {
					if (text.equals(b.name())) {
						if (b.getKeyCount() == 0) {
							if (type == 1) {
								KeyCode_Telex code_Telex =
										KeyCode_Telex.fromString(c);
								return swap(b, code_Telex);
							} else if (type == -1) {
								KeyCode_VNI code_VNI =
										KeyCode_VNI.fromString(c);
								return swap(b, code_VNI);
							}
						}
						return b;
					}
				}
			} else {
				return k;
			}
		}
		return UNDEFINED;
	}

}
